﻿using MaterialDesignThemes.Wpf;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.DirectoryServices;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
using UIWindow.Commands;
using UIWindow.Enums;
using UIWindow.GlobalParameters;
using UIWindow.Helper;
using UIWindow.Lucifer;
using UIWindow.Models;
using UIWindow.SerialServerObject;
using UIWindow.Views.Dialogs;

namespace UIWindow.ViewModels
{
    public class DeviceConfigViewModel
    {
        public ObservableCollection<SerialServerModel> DeviceList { get; set; }
        /// <summary>
        /// 是否是多设备
        /// </summary> 
        public bool IsDevices { get; set; }
        public bool IsNet { get; set; }
        public DeviceType Types { get; set; }
        private readonly UdpClient udpClient;
        public string StartAddress { get; set; }
        public int StartProt { get; set; }
        public string EndAddress { get; set; }
        public int EndPort { get; set; }
        public DeviceGlobal MyDevice { get; set; }
        public string SerialServerName { get; set; }
        public DeviceConfigViewModel(DeviceGlobal device)
        {
            MyDevice = device;
            DeviceList = new ObservableCollection<SerialServerModel>();
            udpClient = new UdpClient(new IPEndPoint(IPAddress.Any, 22345));
            udpClient.Client.ReceiveTimeout = 3000;
            IsNet = true;
        }

        private ISerialServer GetSerialServer()
        {
            return SerialServerName switch
            {
                "IP_Search(1.2)" => new IP_Search_1_2(),
                "HLK_Discover" => new HLK_Discover(),
                _ => null,
            };
        }

        /// <summary>
        /// 搜索设备
        /// </summary>
        public DelegateCommand<Button> SearchDevice => new DelegateCommand<Button>(async sender =>
        {
            DeviceList.Clear();
            _ = DialogHost.Show(new LoadingDialogs(), "RootDialog").ConfigureAwait(false);
            var list = await Task.Run(() =>
            {
                ISerialServer serialServer = GetSerialServer();
                List<SerialServerModel> list = new List<SerialServerModel>();
                IPEndPoint endpoint = new IPEndPoint(IPAddress.Any, 000);
                byte[] buffer = serialServer.GetStream();
                foreach (var item in Dns.GetHostEntry(Dns.GetHostName()).AddressList.Where(x => x.AddressFamily == AddressFamily.InterNetwork))
                {
                    string[] strIP = item.ToString().Split('.');
                    udpClient.Send(buffer, buffer.Length, new IPEndPoint(IPAddress.Parse($"{strIP[0]}.{strIP[1]}.{strIP[2]}.255"), serialServer.Port));
                }
                while (true)
                {
                    try
                    {
                        byte[] bytes = udpClient.Receive(ref endpoint);
                        var model = serialServer.Parsing(bytes, endpoint);
                        if (!list.Any(x => x.IPAddress == model.IPAddress)) list.Add(model);
                    }
                    catch (SocketException)
                    {
                        break;
                    }
                }
                return list;
            });
            foreach (var item in list)
            {
                DeviceList.Add(new SerialServerModel()
                {
                    Mark = item.Mark,
                    MAC = item.MAC,
                    IPAddress = item.IPAddress,
                    Number = item.Number
                });
            }
            DialogHost.CloseDialogCommand.Execute(new object(), sender);
        });

        /// <summary>
        /// 生成服务地址
        /// </summary>
        public DelegateCommand AfterWeighingServer => new DelegateCommand(() =>
        {
            switch (IsDevices)
            {
                case true:
                    MyDevice.AddDevices(StartAddress, StartProt.ToString(), EndAddress, EndPort.ToString(), IsNet, Types);
                    break;
                case false:
                    MyDevice.Add(StartAddress, StartProt, StartProt, IsNet, Types);
                    break;
            }
        });

        public IEnumerable<DeviceType> Foods
        {
            get
            {
                foreach (DeviceType c in (DeviceType[])Enum.GetValues(typeof(DeviceType)))
                {
                    if (c.GetHashCode() < 125) yield return c;
                }
            }
        }

        /// <summary>
        /// 保存配置
        /// </summary>
        public DelegateCommand<Button> SaveInit => new DelegateCommand<Button>(sender =>
        {
            MyDevice.Save();
            "通信配置数据已保存成功！！！".MessageDialogs(MessageLevelType.Info);
        });

        /// <summary>
        /// 根据网址打开指定的浏览器
        /// </summary>
        public DelegateCommand<SerialServerModel> MouseDoubleClick => new DelegateCommand<SerialServerModel>(sender => Process.Start("explorer.exe", $"http://{sender?.IPAddress}"));
    }
}
